<template>
  <div class="courseTask">
    <div class="introduction" v-if="courseInfo">
      <span v-if="courseInfo.currDesc || courseInfo.description">简介： {{ courseInfo.currDesc || courseInfo.description
        }}</span>
      <br />
      <span v-if="courseInfo.goal">课程目标：{{ courseInfo.goal }}</span>
    </div>
    <div v-if="content && !content.length">暂无任务组</div>
    <div class="taskForce">
      <el-collapse v-model="groupActiveName" accordion @change="handleGroupChange">
        <el-collapse-item v-for="(item, index) in content" :key="index" ref="tasks" :id="'parentCollapse-' + index"
          :name="`${index}`">
          <div class="retract" @click="retractTasks(index)" />
          <template slot="title">
            <div style="
                display: flex;               
                align-items: flex-start;
                max-width: 100%;
                height: 100%;
                flex: 1;
              ">
              <div v-if="!unShowGroupIcon && userInfo.accessToken && isChoose" class="taskGrouptNFinishIcons">
                <img src="../../../../assets/images/taskUnfinish.png" class="tNfinishIcon"
                  v-if="item.state == taskState['unstudy']" />
                <img src="../../../../assets/images/taskLearning.png" class="tNfinishIcon"
                  v-if="item.state == taskState['studying']" />
                <img src="../../../../assets/images/taskFinish.png" class="tNfinishIcon"
                  v-if="item.state == taskState['studied']" />
              </div>
              <div class="groupAndtaskIconPath">
                <img :src="item.iconPath" />
              </div>
              <div class="taskName" style=" font-size: 20px;">{{ item.name }}</div>
              <div class="mustInput" v-if="item.name == '' && submissionCourseInfoStatus" title="任务组名必填">
                *
                <!-- <img
                  src="../../../../assets/images/mutIcon.png"
                  title="任务组名必填"
                  @click.stop.prevent
                />-->
              </div>
              <!-- 设置时间 -->
              <setTime :taskGroupID="item.taskGroupID" :type="'taskGroup'" @handleChangeTime="handleChangeTime"
                @handleConfirm="handleConfirmTime" v-if="pageRouteIsTeacher" ref="gSetTime" />
            </div>
            <div class="icondown2Box">
              <img src="../../../../assets/images/down.png" class="downIcon" />
            </div>
          </template>
          <div class="task-content">
            <template>
              <el-collapse v-model="activeNames" @change="handleChange">
                <el-collapse-item v-if="!item.tasks.length" :disabled="true">
                  <template slot="title">暂无任务</template>
                </el-collapse-item>
                <el-collapse-item v-for="(titem, tindex) in item.tasks" :key="tindex" :class="{
      isFinishAndLearing:
        titem.state == taskState['studying'] ||
        titem.state == taskState['studied'],
      isChoose: isChoose,
      isHide: getIsHide(titem.taskID) && !pageRouteIsTeacher,
    }" :name="titem.taskID">
                  <template slot="title">
                    <div style="
                        padding-top: 5px;
                        padding-bottom: 5px;
                        display: flex;
                        align-items: flex-start;
                        max-width: 100%;
                        height: 100%;
                        flex: 1;
                      ">
                      <div v-if="titem.state == taskState['unstudy'] && !unShowGroupIcon">
                        <img src="../../../../assets/images/unlock.png" class="tNfinishIcon"
                          v-if="titem.ableLearn && isChoose" />
                        <img src="../../../../assets/images/lock.png" class="tNfinishIcon" v-else />
                      </div>
                      <div class="groupAndtaskIconPath">
                        <img :src="titem.iconPath" />
                      </div>
                      <div class="taskName" style="min-width: 20px">
                        {{ titem.name }}
                      </div>
                      <div class="mustInput" v-if="titem.name == '' && submissionCourseInfoStatus" title="任务名必填">
                        *
                        <!-- <img
                          src="../../../../assets/images/mutIcon.png"
                          title="任务名必填"
                          @click.stop.prevent
                        />-->
                      </div>
                      <!-- 倒计时 -->
                      <TimeRema :unShowGroupIcon="unShowGroupIcon" :chooseNo="chooseNo"
                        :timeSetting="nTaskSettings[titem.taskID]" :item="item" :titem="titem" :finishTaskData="{
      currNo: Number(courseInfo.currNo),
      taskIndex: item.taskGroupID + '-' + titem.taskID,
      taskGroupID: item.taskGroupID,
      taskID: titem.taskID,
      name: titem.name,
    }" @handlePlanFinishTask="handlePlanFinishTask" ref="TimeRema" v-if="showTimeRema(titem.taskID, $event) &&
      userInfo.userID &&
      chooseNo
      " />
                    </div>
                    <!-- 设置时间 -->
                    <setTime :taskGroupID="item.taskGroupID" :taskID="titem.taskID" :beginTime="titem.beginTime"
                      :cutOffTime="titem.cutOffTime" :type="'task'" :taskSettings="nTaskSettings"
                      @handleChangeTime="handleChangeTime" @handleConfirm="handleConfirmTime" v-if="pageRouteIsTeacher"
                      ref="tSetTime" />
                    <span style="margin-right: 10px;" @click.stop v-if="pageRouteIsTeacher">
                      <el-switch v-if="pageRouteIsTeacher" v-model="titem.isHide" active-color="#13ce66"
                        inactive-color="#ff4949" @click.stop @change="handleChangeIsHide(titem)">
                      </el-switch>
                      {{ titem.isHide ? '隐藏' : '显示' }}
                    </span>
                    <!-- 投票 -->
                    <VoteBtn style="margin-right:20px;" :taskGroupID="item.taskGroupID" :taskID="titem.taskID"
                      :canVote="titem.canVote" :taskSettings="nTaskSettings" :isSetCanVote="true"
                      @handleConfirm="handleConfirmVote" v-if="pageRouteIsTeacher"
                      :title="!isCanVote(titem.taskID) ? '开启投票' : '关闭投票'" />
                    <VoteBtn style="margin-right:20px;" :taskSettings="nTaskSettings" :taskID="titem.taskID"
                      :canVote="titem.canVote" @openVoteDialog="openVoteDialog" v-if="pageRouteIsTeacher"
                      :title="getVoteID(titem.taskID) ? '编辑投票' : '创建投票'" />
                    <VoteBtn style="margin-right:20px;" :taskSettings="nTaskSettings" :taskID="titem.taskID"
                      :canVote="titem.canVote" @openVoteDialog="handleOpenEditVoteItem"
                      :voteItemID="getVoteItemID(titem)" title="编辑投票"
                      v-if="getVoteItemID(titem) && titem.state == taskState['studied']" />
                    <VoteBtn style="margin-right:20px;background-color: #f6ad35;" :taskSettings="nTaskSettings"
                      :taskID="titem.taskID" :canVote="titem.canVote" @openVoteDialog="handleFixedVoteItem(titem)"
                      :voteItemID="getVoteItemID(titem)" title="修复投票"
                      v-if="getVoteItemID(titem) && titem.state == taskState['studied']" />
                    <!-- 学习页面 任务按钮栏 -->
                    <div class="taskController"
                      v-if="titem.state && isChoose && (!titem.isGroupTask || (titem.isGroupTask && getIsGroupLeader(titem))) && successGetStudyData">
                      <el-switch style="margin-right: 10px" v-model="titem.isPublic" active-text="公开" v-if="titem.resultAccessType == '可公开' &&
      myStudyData &&
      titem.ableLearn &&
      (titem.state == taskState['studying'] ||
        titem.state == taskState['studying'])
      " @change="changeMyStudyDataTaskFieldData(
      {
        taskID: titem.taskID,
        currNo: courseInfo.currNo,
        taskGroupID: item.taskGroupID,
      },
      'isPublic',
      titem.isPublic)">
                      </el-switch>
                      <button class="saveData" @click.stop="
      handelSubmitData({
        currNo: Number(courseInfo.currNo),
        taskIndex: item.taskGroupID + '-' + titem.taskID,
        taskGroupID: item.taskGroupID,
        taskID: titem.taskID,
        name: titem.name,
        taskitem: titem
      }, false, null, false, titem)
      " v-if="myStudyData &&
      titem.ableLearn &&

      (titem.state == taskState['studying'] ||
        titem.state == taskState['studying'])
      ">
                        保存
                      </button>
                      <!-- 学生投票 -->
                      <stuCreateVoteItem :nTaskSettings="nTaskSettings" :courseInfo="courseInfo" :titem="titem"
                        class="saveData" v-if="isCanVote(titem.taskID) && checkNotCreateVoteItem(titem)"
                        v-show="(titem.state == taskState['studied'])" @SaveVoteItemID="SaveVoteItemID"
                        :ref="`stuCreateVoteItem-${titem.taskID}`" />
                      <button @click.stop="
      handelTaskBtn(item, titem, {
        currNo: Number(courseInfo.currNo),
        taskIndex: item.taskGroupID + '-' + titem.taskID,
        taskGroupID: item.taskGroupID,
        taskID: titem.taskID,
        name: titem.name,
      })
      " :class="{
      startLearning: titem.state == taskState['unstudy'],
      endLearn:
        titem.state == taskState['studying'] ||
        titem.state == taskState['studying'],
      reLearning: titem.state == taskState['studied'],
    }" v-if="myStudyData &&
      titem.ableLearn &&

      titem.state !== taskState['studying'] &&
      titem.state !== taskState['studying']
      ">
                        {{
      titem.state == taskState['unstudy']
        ? courseInfo.courseType !== '比赛' ? "开始学习" : "查看详情"
        : titem.state == taskState['studied']
          ? courseInfo.courseType !== '比赛' ? "重新学习" : "重新提交"
          : ""
    }}
                      </button>
                      <button @click.stop="
      handelShowDialog(item, titem, {
        currNo: Number(courseInfo.currNo),
        taskIndex: item.taskGroupID + '-' + titem.taskID,
        taskGroupID: item.taskGroupID,
        taskID: titem.taskID,
        name: titem.name,
      })
      " :class="{
      startLearning: titem.state == taskState['unstudy'],
      endLearn:
        titem.state == taskState['studying'],
      reLearning: titem.state == taskState['studied'],
    }" v-if="myStudyData &&
      titem.ableLearn &&

      titem.state == taskState['studying']
      ">
                        {{ courseInfo.courseType !== '比赛' ? '完成学习' : '提交' }}
                      </button>
                    </div>
                    <div class="taskController" v-if="titem.isGroupTask && !getIsGroupLeader(titem)">
                      该任务只能组长提交
                    </div>
                    <div class="icondown2Box" :class="{ btnUnShow: !titem.state }">
                      <!-- <i class="iconfont iconDownxiangxia28" /> -->
                      <img src="../../../../assets/images/down2.png" class="downIcon" />
                    </div>
                  </template>
                  <div>
                    <div class="taskDesc">
                      <span v-if="titem.description" class="desc">简介：
                        <span v-html="titem.description"></span>
                      </span>
                      <br />
                      <span v-if="titem.goal"> 目标：{{ titem.goal }}</span>
                      <!-- <div
                        class="chioceInput"
                        v-if="
                          (titem.description == '' || titem.goal == '') &&
                          submissionCourseInfoStatus
                        "
                        :title="
                          courseInfo.description == ''
                            ? '任务简介选填'
                            : courseInfo.goal == ''
                            ? '任务目标选填'
                            : '选填'
                        "
                      >
                        *
                      </div>-->
                    </div>
                    <div v-loading="loadingTasks.indexOf(`${index + '-' + tindex}`) != -1
      ">
                      <TaskType v-for="(ditem, dindex) in titem.guidelines" :courseID="courseInfo.courseID"
                        :currNo="courseInfo.currNo" :chooseNo="chooseNo" :taskID="titem.taskID"
                        :taskGroupID="titem.taskGroupID" :ref="'taskType' + item.taskGroupID + '-' + titem.taskID
      " :userId="userInfo.userID" :item="item" :titem="titem" :cTaskState="titem.state" :guidelineObj="ditem"
                        :thisIndex="ditem.noInTask" :key="dindex" :isChoose="isChoose"
                        @fetchNewtaskCommitJsonData="fetchNewtaskCommitJsonData" :unShowGroupIcon="unShowGroupIcon"
                        :submissionCourseInfoStatus="submissionCourseInfoStatus"
                        @handleChangeSubmitContent="handleChangeSubmitContent" :myStudyData="myStudyData"
                        @handleUpdateSessionID="handleUpdateSessionID" @handleUpdateTaskScore="handleUpdateTaskScore"
                        :creativeCourse="creativeCourse" @handleUploadFile="handleUploadFileSaveData"
                        :tutorStaffUserID="courseInfo.tutorStaffUserID"
                        :tutorIDToClassIDMap="courseInfo.tutorIDToClassIDMap"
                        :mainDesignerUserID="courseInfo.mainDesignerUserID"
                        :otherDesigerUserIDList="courseInfo.otherDesigerUserIDList" :nTaskSettings="getNewTaskSetting"
                        :selectedTutorName="selectedTutorName"
                        :onlyShowGuideline="titem.isGroupTask && !getIsGroupLeader(titem)" />
                    </div>
                  </div>
                </el-collapse-item>
              </el-collapse>
            </template>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
    <!-- 完成学习确认框 -->
    <el-dialog :visible.sync="confirmFinishTask" width="240px" center class="finishDialog">
      <div class="title" v-if="courseInfo.courseType !== '比赛'">确认完成学习</div>
      <div class="title" v-else>确认提交</div>
      <div class="tips" v-if="courseInfo.courseType !== '比赛'">完成学习后，需重新学习才能修改答案！</div>
      <div class="tips" v-else>提交后,需要重新提交才能修改提交内容。</div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="confirmFinishTask = false">取 消</el-button>
        <el-button type="primary" @click="handelConfirm(null, null, true, null)">确 定</el-button>
      </span>
    </el-dialog>
    <createEditVote :title="`${iframeRouter.indexOf('add') !== -1 ? '创建' : '修改'}投票`" :iframeShow="showVoteDialog"
      :iframeRouter="iframeRouter" :checkTeacher="checkTeacher" :selectedTutorName="selectedTutorName" :isVote="true"
      v-if="pageRouteIsTeacher || showVoteDialog" @handleIframeClose="handleIframeClose"
      @saveVoteInfo="handleConfirmVote" />
  </div>
</template>

<script>
import { operType, taskState } from "@/util/guidingtextType";
const TaskType = () => import("./taskType_N/taskType_N");
import { getChooseUpdateTaskResult, updateTaskstate } from "@/request/courses";
import { mapState } from "vuex";
import {
  location,
  isJSONstr,
  changeSubmitContentfomart,
  toMs,
} from "@/util/tool";
import { updatecurr } from "@/request/courses";
import { formatCourseGroupTaskObj } from "@/util/courseData";
const setTime = () => import("@/views/courses/detail/task_N/compoment/setTime");
const VoteBtn = () => import("@/views/courses/detail/task_N/compoment/VoteBtn");
const createEditVote = () => import("@/components/questionBankIframeDialog/index");
const TimeRema = () =>
  import("@/views/courses/detail/task_N/compoment/timeRema");
const stuCreateVoteItem = () => import("@/views/courses/detail/task_N/compoment/stuCreateVoteItem")
import { location_QuestionBank } from "@/util/tool";
import { getNewTaskStudyData, getNewGuidelineStudyData } from "@/util/mockTaskData.js"
import { updateVoteItem } from "@/request/vote"
import { sendMessageByClient } from "@/util/msgjs/addSocketMsg";
import { getVoteItem } from "@/request/vote"
export default {
  // name: "Task",
  components: {
    TaskType,
    setTime,
    TimeRema,
    VoteBtn,
    createEditVote,
    stuCreateVoteItem
  },
  data() {
    return {
      operType,
      taskState,
      content: [],
      groupActiveName: '0',
      activeNames: [],
      loadingTasks: [],
      confirmFinishTask: false,
      currGroupitem: {}, // 当前点击的对象数据
      currTaskitem: {}, // 当前点击的对象数据
      location: location(window),
      isLinstened: false, // 离开页面/刷新页面前的监听是否开启
      unSaveTaskID: [], // 记录任务未保存状态
      pageRouteIsStudy: false, // 是否在学习页面
      pageRouteIsTeacher: false, // 是否在教师查看详情页面
      nTaskSettings: null,
      showVoteDialog: false, // 显示弹窗
      iframeRouter: "", // 投票弹窗地址
      taskID_Vote: null, // 投票任务ID
      roomName: `currNo_`,
      currNo: null,
    };
  },
  props: {
    courseInfo: Object,
    myStudyData: Array,
    isGroupLeader: Boolean,
    chooseNo: Number, // 学生选修ID
    unShowGroupIcon: Boolean, // 在教师查看课程详情页面属于控制类参数
    learnGroupIndex: String, // 默认展开的的任务组或任务
    submissionCourseInfoStatus: Boolean, // 提交创作系统数据的状态
    isChoose: Boolean, // 已选课
    creativeCourse: Boolean, // 创作系统调用
    checkTeacher: Number, // 指导教师id
    selectedTutorName: String, // 指导教师名字
    successGetStudyData: Boolean, // 是否成功获取学习数据
  },
  watch: {
    // learnGroupIndex(newValue, o) {
    //   // this.$nextTick(() => {
    //   if (newValue) {
    //    // this.activeNames.push(newValue.split("-")[0]);
    //     this.activeNames.push(newValue);
    //   }
    //   // })
    // },
    courseInfo(newValue) {
      this.handleInitTaskComponent(newValue);
    },
    // 任务学习进度
    content(n) {
      this.handleChangeCourseLearnPro();
    },
    unSaveTaskID(newValue) {
      // 如果所有任务都保存完 关闭浏览器离开的监听
      if (newValue.length === 0 && this.isLinstened) {
        this.destroyedBeforeunloadHandler();
      }
    },
    "courseInfo.taskSettings"(newValue) {
      this.nTaskSettings = newValue || {};
    },
  },
  computed: {
    ...mapState({
      userInfo: (state) => state.user.userInfo,
      getChooseCourses: function (state) {
        return state.courses.chooseCourses;
      },
      socketClient: (state) => state.danmu.socketClient,
    }),
    client() {
      return this.socketClient;
    },
    getNewTaskSetting() {
      return this.nTaskSettings;
    },
    showTimeRema() {
      return (taskID, e) => {
        return (
          this.getNewTaskSetting?.[taskID]?.state == "生效"
        );
      };
    },
    isCanVote() {
      return (taskID) => {
        return this.getNewTaskSetting?.[taskID]?.canVote
      }
    },
    getVoteID() {
      return (taskID) => {
        return this.getNewTaskSetting?.[taskID]?.voteID;
      }
    },
    getVoteItemID() {
      return (titem) => {
        return titem?.guidelines[0]?.studyData?.voteItemID
      }
    },
    checkNotCreateVoteItem() {
      return (titem) => {
        return !this.getVoteItemID(titem)
      }
    },
    isCompetition() {
      return this.courseInfo.courseType == "比赛"
    },
    getIsHide() {
      return (taskID) => {
        return this.getNewTaskSetting?.[taskID]?.isHide;
      }
    },
    // 获取任务的学习数据判断是不是小组长
    getIsGroupLeader() {
      return (titem) => {
        if (titem.isGroupTask) { //如果没有学习数据呢？
          //const findTaskData = this.myStudyData?.find(dItem => dItem.taskID === titem.taskID)
          return this.$props.isGroupLeader  // findTaskData ? findTaskData.isGroupLeader : false
        } else {
          return false
        }
      }
    },
  },
  created() {
    this.currNo = this.$route.params.id
    this.pageRouteIsStudy = this.$route.path.indexOf("curr") !== -1;
    this.pageRouteIsTeacher =
      this.$route.path.indexOf("csetting") !== -1;
    if (this.courseInfo.taskGroups)
      this.handleInitTaskComponent(this.courseInfo);
    if (this.courseInfo.taskSettings)
      this.nTaskSettings = this.courseInfo.taskSettings
  },
  methods: {
    // 初始化当前组件的数据
    handleInitTaskComponent(courseInfo) {
      let data = JSON.parse(JSON.stringify(courseInfo)) // 此处需要深复制
      if (this.pageRouteIsStudy) {
        this.handleCheckAllTaskResult(data.taskGroups); // 给课程数据的引导文对象添加学习数据
      }
      formatCourseGroupTaskObj(data, this); // 课程数据任务组对象、任务对象、引导文对象 转数组
      if (this.pageRouteIsStudy) {
        this.handleAddState(data);
      }
      this.content = data.content;
      if (this.content && this.content[0] && this.content[0].tasks) {
        this.activeNames = this.content[0].tasks.map(item => item.taskID)

      }
    },
    handleChange(val) {//调试任务组面板
      //console.log(val)
    },
    handleGroupChange(val) {//显示任务面板的第一个
      //console.log(val)
      if (val && this.content[val].tasks && this.content[val].tasks.length) {
        if (this.activeNames.findIndex(item => item == this.content[val].tasks[0].taskID) == -1)
          this.activeNames.push(this.content[val].tasks[0].taskID)
      }
    },
    // 调用父组件函数获取新的学习数据
    fetchNewtaskCommitJsonData() {
      return new Promise((resolve, reject) => {
        const currNo = this.courseInfo.currNo;
        let fetchCoursesData = this.$parent.fetchCoursesData({
          currNo: currNo,
          userID: this.userInfo.userID,
        });
        fetchCoursesData.then((res) => {
          if (res.errno === 0) {
            // this.$parent.handelData();
            resolve(res.data);
          } else {
            // this.$antdMessage.error({
            //   content: '数据同步失败，请刷新页面！'
            // })
            resolve(false);
          }
        });
      });
    },
    // 收起折叠组件
    retractTasks(index) {
      this.$refs.tasks[index].handleHeaderClick();
    },
    // 打开完成任务对话框
    async handelShowDialog(groupitem, taskitem, data) {
      let checkTaskTime = await this.handleCheckTaskTimeState(taskitem);
      if (!checkTaskTime) return;
      let myStudyData = localStorage.getItem("studyData")
        ? JSON.parse(localStorage.getItem("studyData"))
        : {};
      let getCurrStudyData = myStudyData[data.currNo][this.userInfo.userID];
      const currTaskData = getCurrStudyData.find(
        (item) => item.taskID == data.taskID
      );
      let unFinish = false
      // 任务内没有引导文学习数据
      if (!currTaskData.guidelineResults) {
        this.$antdMessage.warning({ content: "当前任务内没有学习数据，请刷新页面" })
        return
        // currTaskData.guidelineResults = {}
        // this.fixTaskNoStudyData(currTaskData.guidelineResults, groupitem, taskitem)
      }
      /**
       * 过滤被删除的引导文
       * 当引导文的学习数据被创建后会一直存在，不管引导文以后是否会被删除，这里需要过滤。只判断当前存在的引导文是否有学习
       */
      Object.keys(currTaskData.guidelineResults).forEach(key => { currTaskData.guidelineResults[key].guidelineID = key })
      currTaskData.guidelineResults = Object.values(currTaskData.guidelineResults).filter(item => taskitem.guidelines.some(sitem => sitem.guidelineID == item.guidelineID))
      Object.keys(currTaskData.guidelineResults).forEach(key => {
        if (unFinish) return
        const guideline = currTaskData?.guidelineResults[key]
        if (guideline) {
          const findGuideline = taskitem.guidelines.find(item => item.guidelineID == guideline.guidelineID)
          if (findGuideline?.operType !== operType['refer']) {
            if (findGuideline?.operType == operType['show']) {
              let gShowData = guideline?.submitContent.data
              if (!gShowData || !gShowData.showLink) {
                unFinish = true
                console.log('展示类型数据', guideline, gShowData)
                return this.$antdMessage.warning({ content: "当前任务尚有引导文未完成!" })
              }
            }
            else {
              let gData = guideline?.submitContent?.data
              const gCourseData = this.courseInfo?.taskGroups?.[groupitem.taskGroupID]?.tasks?.[taskitem.taskID]?.guidelines[guideline.guidelineID]
              if (((gCourseData.operType == operType['upload'] || gCourseData.operType == operType['archive']) && !gData && !gData?.filePaths?.length) || (gCourseData.operType == operType['reply'] && !gData) || ((gCourseData.operType == operType['brush'] || gCourseData.foreignID) && !guideline.session_id)) {
                unFinish = true
                return this.$antdMessage.warning({ content: "当前任务尚有引导文未完成!" })
              }
            }
          }
        } else {
          unFinish = true
          return this.$antdMessage.warning({ content: "没有学习数据,无法完成!" })
        }
      })
      if (unFinish) return
      this.currGroupitem = groupitem;
      this.currTaskitem = taskitem;
      this.currData = data;
      this.confirmFinishTask = true;
    },
    // 确认对话框
    async handelConfirm(groupitem, taskitem, isAuto, notifyEl, isCheck) {
      this.confirmFinishTask = false;
      // 判断是否有未保存的数据 等待处理
      const isCreated = await this.autoCreateVoteItem()
      // this.$antdMessage.error({content: "创建投票项失败!", duration: 5})
      // if (!isCreated) return
      // 如果是第一次点击没有this.currData
      if (this.currData) {
        let pull = await this.handelUnpullData(this.currData, isAuto, notifyEl);
        if (pull === undefined || pull) return
      }
      await this.handelTaskBtn(
        groupitem || this.currGroupitem,
        taskitem || this.currTaskitem,
        this.currData,
        isAuto,
        notifyEl,
        isCheck
      );
    },
    // 自动创建投票项
    autoCreateVoteItem() {
      // 延迟处理
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const taskID = this.currData?.taskID
          if (this.currTaskitem.canVote && this.checkNotCreateVoteItem(this.currTaskitem)) {
            const getVoteID = this.getNewTaskSetting?.[taskID]?.voteID
            if (getVoteID) {
              this.$nextTick(async () => {
                const getTaskVoteComponent = this.$refs[`stuCreateVoteItem-${taskID}`]?.[0]
                if (getTaskVoteComponent) {
                  const isCreated = await getTaskVoteComponent.handleOpenVote(getTaskVoteComponent.titem)
                  if (isCreated) return resolve(true)
                  else return resolve(false)
                } else {
                  // 修复无法创建任务投票时，任务无法完成
                  return resolve(false)
                }
              })
            } else return resolve(true)
          } else return resolve(true)
        }, 300);
      })
    },
    // 获取本地学习数据 判断当前任务是否有数据还未提交
    async handelUnpullData(data, isAuto, notifyEl) {
      let currTaskData = this.getLocalStorageTaskData(data);
      const oldTaskState = currTaskData.state
      // 判断任务是否有学习数据 或 任务是否还未保存
      if (currTaskData?.notSaved) {
        let changeToState =
          currTaskData.state == taskState['unstudy']
            ? "在学"
            : currTaskData.state == taskState['studying']
              ? "已学"
              : "在学";
        // 成功什么都不反回
        const res = await this.handelSubmitData(
          this.currData,
          isAuto,
          notifyEl,
          changeToState,
          this.currTaskitem
        )
        if (res) {
          this.changeToTaskStated(this.currGroupitem, this.currTaskitem, {
            state: changeToState,
          });
          // const msg = oldTaskState == "未学" ? "开始学习" : oldTaskState == "在学" ? "完成学习" : "重新学习";
          const msg = this.getMessage(oldTaskState, isAuto, this.isCompetition)
          this.sendMessage(msg + data.name)
          // this.handelTaskBtn(
          //   this.currGroupitem,
          //   this.currTaskitem,
          //   this.currData,
          //   isAuto,
          //   notifyEl
          // );
          return Promise.resolve(true);
        } else {
          this.$antdMessage.error({
            content: "系统提交未保存的数据时发生错误！",
          });
        }
      } else {
        return Promise.resolve(false);
      }
    },
    // 任务的按钮
    async handelTaskBtn(groupitem, taskitem, data = {}, isAuto, notifyEl, isCheck = false) {
      if (!isAuto) {
        let checkTaskTime = await this.handleCheckTaskTimeState(taskitem);
        if (!checkTaskTime) return;
      }
      // 修复data是空对象
      data = {
        currNo: Number(this.courseInfo.currNo),
        taskIndex: groupitem.taskGroupID + '-' + taskitem.taskID,
        taskGroupID: groupitem.taskGroupID,
        taskID: taskitem.taskID,
        name: taskitem.name,
      }
      // 获取当前任务
      let myStudyData = localStorage.getItem("studyData")
        ? JSON.parse(localStorage.getItem("studyData"))
        : {};
      let getCurrStudyData =
        myStudyData?.[this.courseInfo.currNo]?.[this.userInfo.userID];
      let currTaskData = getCurrStudyData?.find(
        (item) => item.taskID == data.taskID
      );
      if (!currTaskData) {
        currTaskData = getNewTaskStudyData(groupitem.taskGroupID, taskitem, this.chooseNo, this.courseInfo.currNo);
        getCurrStudyData.push(currTaskData);
        myStudyData[this.courseInfo.currNo][this.userInfo.userID] =
          getCurrStudyData;
        localStorage.setItem("studyData", JSON.stringify(myStudyData));
      }

      // 任务内没有引导文学习数据
      if (!currTaskData.guidelineResults) {
        this.$antdMessage.warning({ content: "当前任务内没有学习数据，请刷新页面" })
        return
        // currTaskData.guidelineResults = {}
        // this.fixTaskNoStudyData(currTaskData.guidelineResults, groupitem, taskitem)
      }
      let check = isCheck || false
      // 当开始学习的时候 可能会出现当前任务下含有新发布的引导文 但原有的学习数据不含有新发布的引导文数据
      if (
        (taskitem.guidelines.length >
          Object.keys(currTaskData.guidelineResults).length) && !check
      ) {
        taskitem.guidelines.forEach((gitem) => {
          // 如果没有这个引导文的学习数据 则添加一个引导文数据到当前任务学习数据(currTaskData: Object)里面
          if (!currTaskData.guidelineResults[gitem.guidelineID] && gitem.operType !== '查阅') {
            currTaskData.guidelineResults[gitem.guidelineID] =
              getNewGuidelineStudyData(gitem);
            currTaskData.notSaved = true;
          }
        });
        let studyDataIndex = getCurrStudyData.findIndex(
          (ftitem) => ftitem.taskID == data.taskID
        );
        getCurrStudyData[studyDataIndex] = currTaskData;
        myStudyData[this.courseInfo.currNo][this.userInfo.userID] =
          getCurrStudyData;
        localStorage.setItem("studyData", JSON.stringify(myStudyData));
        // 因为当前任务的学习数据不完整 需要先修改学习数据 因此这里可以调用(handelConfirm: Function)
        // 调用时需要把handelTaskBtn需要的参数传入
        check = true
        this.handelConfirm(groupitem, taskitem, false, null, check);
        return;
      }

      let params = {
        state: currTaskData.state,
        currNo: Number(currTaskData.currNo),
        taskID: Number(currTaskData.taskID),
        chooseNo: Number(currTaskData.chooseNo),
        courseID: Number(this.courseInfo.courseID)
      };
      params.taskID = Number(taskitem.taskID);
      params.taskGroupID = Number(groupitem.taskGroupID);
      if (!params.chooseNo) {
        let findMyCourse = this.getChooseCourses.find(mitem => mitem.currNo == this.courseInfo.currNo)
        params.chooseNo = Number(findMyCourse.chooseNo)
      }

      if (isAuto) {
        params.state = taskState['studied'];
        params.finishTime = new Date().getTime();
      } else if (taskitem.state == taskState['unstudy']) {
        params.state = taskState['studying'];
        params.startTime = new Date().getTime();
      } else if (taskitem.state == taskState['studying']) {
        params.state = taskState['studied'];
        params.finishTime = new Date().getTime();
      } else {
        // if (taskitem.state == taskState['studied'])
        params.state = taskState['studying'];
      }

      // 如果当前任务的学习数据没有保存 或 当前任务是新添加的任务暂无学习数据
      if (currTaskData.notSaved) {
        let changeToState = params.state;
        let isSaveSubmitContent = await this.handelSubmitData(
          data,
          isAuto,
          notifyEl,
          changeToState,
          taskitem
        );
        isSaveSubmitContent && this.changeToTaskStated(groupitem, taskitem, params);
        let taskGroup = this.content.find(item => item.taskGroupID == data.taskGroupID)
        let task = taskGroup.tasks.find(item => item.taskID == data.taskID)
        // this.loadingTasks.push(data.taskIndex);
        task.guidelines.forEach(g => {
          if (!g.studyData) {
            let myStudyData = localStorage.getItem("studyData")
              ? JSON.parse(localStorage.getItem("studyData"))
              : {};
            let getCurrStudyData = myStudyData[this.courseInfo.currNo][this.userInfo.userID];
            const currTaskData = getCurrStudyData.find(
              (item) => item.taskID == data.taskID
            );
            this.$set(g, 'studyData', currTaskData.guidelineResults[g.guidelineID])
          }
        })
        // 如果新的任务数据没有保存成功
        return Promise.resolve(isSaveSubmitContent);
        // if (!isSaveSubmitContent) return;
      }

      // 只是重新学习 没有修改引导为的lastUpdatedTime 当前接口不会修改引导文数据
      // todo 需要后端设置引导文的lastUpdatedTime
      // Object.keys(params.guidelineResults).forEach(key => {
      //   params.guidelineResults[key].lastUpdatedTime = new Date().getTime()
      // })

      return new Promise((resolve, reject) => {
        updateTaskstate(params).then((res) => {
          if (res.errno === 0) {
            // 如果是自动提交的任务则删除消息
            if (notifyEl) {
              notifyEl.close();
              this.$notify({
                title: "提示",
                message: `${"任务：" + taskitem.name + "，已自动完成学习。"}`,
                duration: 3000,
                type: "success",
              });
            }
            const msg = this.getMessage(taskitem.state, isAuto, this.isCompetition)
            // const msg =  isAuto
            //     ? "完成学习"
            //     : (taskitem.state == taskState['unstudy'] || !taskitem?.state)
            //     ? "开始学习"
            //     : taskitem.state == taskState['studying']
            //     ? "完成学习"
            //     : taskitem.state == taskState['studied']
            //     ? "重新学习"
            //     : "完成学习"
            this.$antdMessage.success({
              content: msg,
            });
            // + taskitem.name
            this.sendMessage(msg + data.name)
            this.handleRemoveUnSaveTaskIDMark(params.taskID);
            this.changeToTaskStated(groupitem, taskitem, params);
            resolve(true)
          } else {
            this.$antdMessage.error({
              content: res.message,
            });
            resolve(false)
          }
        });
      })
    },
    // 模拟任务数据
    fixTaskNoStudyData(obj, groupitem, taskitem) {
      taskitem.guidelines.forEach(guideline => {
        // 模拟数据格式 查阅类型除外
        if ((guideline.operType && guideline.operType !== '查阅')) { //  || taskitem.guidelines.length === 1
          obj[guideline.guidelineID] = getNewGuidelineStudyData(guideline);
        }
      })
    },
    // 根据任务状态获取对应消息
    getMessage(tSate, isAuto, isCompetition = this.isCompetition) {
      if (isAuto) return isCompetition ? "提交" : "完成学习"
      let msg = {
        "未学": "开始学习",
        "在学": "完成学习",
        "已学": "重新学习"
      }
      let msg_competition = {
        "未学": "查看详情",
        "在学": "已提交",
        "已学": "查看详情"
      }
      return tSate ? isCompetition ? msg_competition[tSate] : msg[tSate] : "开始学习"
    },
    // 改变任务状态后调用
    changeToTaskStated(groupitem, taskitem, params) {
      localStorage.setItem("sData_eTime", new Date().getTime() - 10000);
      this.$set(taskitem, "state", params.state);
      this.$forceUpdate();
      this.handleChangeCourseLearnPro(); // 更新学习进度
      this.changeMyStudyDataTaskFieldData(
        {
          taskID: taskitem.taskID,
          currNo: this.courseInfo.currNo,
          taskGroupID: groupitem.taskGroupID,
        },
        'state',
        params.state
      );
    },
    // 修改本地任务的字段的学习数据
    changeMyStudyDataTaskFieldData(data, field, value) {
      const localData = localStorage.getItem("studyData");
      const studyData = localData ? JSON.parse(localData) : {};
      let myDataFromLocal = studyData[data.currNo]?.[this.userInfo.userID];
      if (myDataFromLocal) {
        let findTask = myDataFromLocal.find(
          (item) => item.taskID == data.taskID
        );
        if (findTask) findTask[field] = value;
        if (!findTask.taskGroupID) findTask.taskGroupID = data.taskGroupID;
        localStorage.setItem("studyData", JSON.stringify(studyData));
      }
    },
    // 提交数据
    handelSubmitData(data, isAuto, notifyEl, changeToState, taskitem, message) {
      return new Promise((resolve, reject) => {
        // 如果获取学习数据失败时
        if (!this.successGetStudyData) {
          this.$antdMessage.warning({
            content: "因获取学习数据失败，禁止提交数据",
          });
          return
        }
        if (!this.userInfo.userID) {
          this.$antdMessage.warning({
            content: "获取身份信息失败无法保存数据，请刷新后重试！",
          });
          return;
        }
        let checkTaskTime = true;
        let _taskItem = taskitem || data.taskitem
        if (_taskItem) {
          this.handleCheckTaskTimeState(_taskItem).then(result => {
            checkTaskTime = result
          });
        }
        if (!checkTaskTime) return;
        // debugger;
        this.loadingTasks.push(data.taskIndex);
        let myStudyData = localStorage.getItem("studyData")
          ? JSON.parse(localStorage.getItem("studyData"))
          : {};
        let getCurrStudyData = myStudyData[data.currNo][this.userInfo.userID];
        const currTaskData = getCurrStudyData.find(
          (item) => item.taskID == data.taskID
        );
        console.log(currTaskData)
        if (currTaskData) {
          const params = Object.assign({}, currTaskData); // 复制一个新的数据 避免内存同步
          params["userID"] = this.userInfo.userID;
          params.currNo = Number(params.currNo)
          params.courseID = this.courseInfo.courseID
          // 未知原因报错 "数据格式校验错误 : /commentUserID should be number"
          if (params.commentUserID) params.commentUserID = Number(params.commentUserID)
          // 如果时直接确认任务完成学习 并任务数据还未保存时
          // => 在调用当前函数保存学习数据时 状态直接改为已学 减少一次接口调用 atTheSameTime ? "已学"
          params.state = isAuto ? "已学" : "在学";
          if (changeToState) {
            params.state = changeToState;
          }
          params.name = data.name;
          // 任务内没有学习数据
          if (!currTaskData.guidelineResults) {
            currTaskData.guidelineResults = {}
            this.fixTaskNoStudyData(currTaskData.guidelineResults, data, data.taskitem)
          }
          // this.fixTaskNoStudyData(currTaskData.guidelineResults, data, data.taskitem)
          params.guidelineResults = Object.assign(
            {},
            currTaskData.guidelineResults
          ); // 格式化引导文数据为对象
          // 将不是任务内的数据去掉
          params.guidelines = undefined;
          params.finishTime = data.finishTime || 0;
          params.isPublic = currTaskData.isPublic;
          if (!params.taskGroupID) params.taskGroupID = data.taskGroupID;

          // 如果是投票任务添加指导教师信息
          if (this.courseInfo.shouldChooseTutor && this.currTaskitem.canVote) {
            params.tutorID = this.checkTeacher
            params.tutorName = this.selectedTutorName
          }

          // 修复学生完成展示任务时，创建了投票项但没有保存到学习数据
          // console.log(params);
          // if (this.userInfo.userID == 322 && params.taskID == 179) {
          //   params.guidelineResults[1].voteItemID = 80
          //   currTaskData.guidelineResults[1].voteItemID = 80
          //   params.state = "已学"
          // }

          // params.lastUpdatedTime = undefined;
          // Object.keys(params.guidelineResults).forEach(key => {
          //   if (params.guidelineResults[key]?.guidelineScore != -8) {
          //     if (Number(params.taskScore) == -8) {
          //       params.taskScore = 0
          //     }
          //     params.taskScore += Number(params.guidelineResults[key].guidelineScore)
          //   }
          // })
          delete params.notSaved;
          const newParams = this.handleFilterFiled(params)
          // 提交数据
          setTimeout(() => {
            getChooseUpdateTaskResult(newParams)
              .then((res) => {
                if (res.errno === 0) {
                  // 如果是自动提交的任务则删除消息
                  if (notifyEl) {
                    notifyEl.close();
                    this.$notify({
                      title: "提示",
                      message: `${"任务：" + params.name + "，已自动完成学习。"
                        }`,
                      duration: 3000,
                      type: "success",
                    });
                  }

                  // 修改任务数据时将url重设
                  // 获取当前任务
                  let findTaskGroup = this.content.find(
                    (item) => item.taskGroupID === data.taskGroupID
                  );
                  const getTask = findTaskGroup?.tasks.find(item => item.taskID == data.taskID)
                  if (getTask) {
                    const VoteID = this.getVoteID(data.taskID)
                    const VoteItemID = this.getVoteItemID(getTask)
                    if (VoteID && VoteItemID) {
                      const oldLink = getTask?.guidelines?.[0]?.studyData?.submitContent?.data?.showLink || ""
                      this.updateVoteItemInfo(currTaskData, oldLink, getTask, VoteID)
                    }
                  }

                  // 移除当前任务 在任务未保存记录中的记录
                  this.handleRemoveUnSaveTaskIDMark(data.taskID);

                  let findTaskIndex = getCurrStudyData.findIndex(
                    (item) => item.taskID == data.taskID
                  );
                  params.notSaved = false;
                  getCurrStudyData[findTaskIndex] = params;
                  myStudyData[data.currNo][this.userInfo.userID] =
                    getCurrStudyData;
                  localStorage.setItem(
                    "studyData",
                    JSON.stringify(myStudyData)
                  );
                  // 如果是在修改任务状态函数中调用当前函数（修改学习数据）
                  if (changeToState) {
                    const msg = this.getMessage(taskitem.state, isAuto, this.isCompetition)
                    // const msg = isAuto
                    //     ? "完成学习"
                    //     : (changeToState == taskState['unstudy'] || taskitem?.state ==taskState['unstudy'])
                    //     ? "开始学习"
                    //     : changeToState == taskState['studying']
                    //     ? "完成学习"
                    //     : "重新学习"
                    this.$antdMessage.success({
                      content: msg,
                    });
                    this.sendMessage(msg + data.name)
                    resolve(true);
                  } else {
                    this.handelLoading(data);
                    // 将当前任务下的引导文设为已提交
                    this.setGuidelinesIsSubmit(data);
                    this.$antdMessage.success({
                      content: message || "保存成功！",
                    });
                    resolve(true);
                  }
                } else {
                  this.$antdMessage.error({
                    content: res.message || res,
                  });
                  this.handelLoading(data);
                  resolve(false);
                }
              })
              .catch((err) => {
                resolve(false);
              });
          }, 150);
        } else {
          this.handelLoading(data);
          this.$antdMessage.warning({
            content: "当前任务没有可提交的数据，请更新引导文内容后再试！",
          });
        }
      });
    },
    // 过滤任务部分字段
    handleFilterFiled(params) {
      const fileds = ['chooseNo', 'courseID', 'currNo', 'groupNoInCourse', 'guidelineResults', 'state', 'tutorID', 'tutorName', 'userID', 'taskID', 'taskGroupID', 'isPublic']
      const obj = {}
      fileds.forEach(key => {
        obj[key] = params[key]
      })
      return obj
    },
    // 检测任务限时状态
    handleCheckTaskTimeState(titem) {
      return new Promise((resolve) => {
        if (!titem) return resolve(true);
        // 如果没有限时数据则通过检测
        if (
          (!this.nTaskSettings && !this.courseInfo?.taskSettings) ||
          !this.nTaskSettings?.[titem.taskID]
        ) {
          return resolve(true);
        } else {
          let timeSetting =
            this.nTaskSettings[titem.taskID] ||
            this.courseInfo.taskSettings[titem.taskID];
          let currTime = new Date().getTime();
          // if (timeSetting.beginTime && timeSetting.cutOffTime) {
          // 任务还未到开始学习时间
          if (
            timeSetting.beginTime &&
            this.toMs(timeSetting.beginTime) > currTime &&
            timeSetting.state == "生效"
          ) {
            if (titem.state == taskState['unstudy']) {
              this.$antdMessage.warning({
                content: "未到开始学习时间！",
              });
              return resolve(false);
            }
          }
          // 任务已经超出学习时间
          if (
            timeSetting.cutOffTime &&
            this.toMs(timeSetting.cutOffTime) < currTime &&
            timeSetting.state == "生效"
          ) {
            // 超出时间时 开始学习、重新学习弹出提示。完成学习不作限制
            if (
              titem.state == taskState['unstudy'] ||
              titem.state == taskState['studied']
            ) {
              this.$antdMessage.warning({
                content: "已超出任务限定学习时间！",
              });
              return resolve(false);
            }
          }
          resolve(true);
        }
      });
    },
    // 任务限时已到 触发成任务
    handlePlanFinishTask(groupitem, taskitem, data, isAuto) {
      this.currGroupitem = groupitem;
      this.currTaskitem = taskitem;
      if (!data.taskGroupID) data.taskGroupID = groupitem.taskGroupID;
      this.currData = data;
      let notifyEl = this.$notify({
        title: "提示",
        message: `${"任务：" + taskitem.name + "，将在10分钟内自动提交！"}`,
        duration: 0,
      });
      // 调用时需要把handelTaskBtn需要的参数传入
      this.handelConfirm(groupitem, taskitem, isAuto, notifyEl);
    },
    // 加载窗口
    handelLoading(data) {
      this.loadingTasks = this.loadingTasks.filter(
        (item) => item !== data.taskIndex
      );
    },
    // 当前任务下的所有引导文组件
    currTaskguideline(data) {
      return this.$refs["taskType" + data.taskGroupID + "-" + data.taskID];
    },
    // 将当前任务下的引导文设为已提交
    setGuidelinesIsSubmit(data) {
      this.currTaskguideline(data).forEach((item) => {
        item.isSubmit = true;
      });
    },
    // 将学习数据赋值到课程信息的引导文中
    handleCheckAllTaskResult(data) {
      const mStudyData = this.myStudyData;
      Object.keys(data).forEach((key) => {
        Object.keys(data[key].tasks).forEach((tkey) => {
          let findHaveTask = mStudyData.find((fmItem) => fmItem.taskID == tkey);
          if (findHaveTask) {
            findHaveTask.chooseNo = this.chooseNo;
            findHaveTask.currNo = this.courseInfo.currNo;
            findHaveTask.taskGroupID = data[key].taskGroupID;
            data[key].tasks[tkey].state = findHaveTask.state;
            data[key].tasks[tkey].isPublic = findHaveTask.isPublic;
            const newGuidelineObj = {};
            Object.keys(data[key].tasks[tkey].guidelines).forEach((gkey) => {
              let findHaveGuideline = findHaveTask.guidelineResults?.[gkey];
              if (findHaveGuideline) {
                data[key].tasks[tkey].guidelines[gkey].studyData =
                  findHaveGuideline;
                newGuidelineObj[gkey] = findHaveGuideline;
              }
            });
            findHaveTask.guidelineResults = newGuidelineObj;
          } else {
            data[key].tasks[tkey].state = taskState['unstudy'];
          }
        });
      });
    },
    // 给courseInfo 每个任务组、任务添加状态
    handleAddState(data) {
      // let learnGroupIndex = 0;
      // let learnTaskIndex = 0;
      data.content.forEach((item, index) => {
        // 设置任务组所有任务的状态
        this.$set(item, "state", taskState['unstudy']);

        // 将所有任务组状态设置为可学习 任务组现在不分先后顺序
        // todo 可以改为：由后台老师来配置，逐个任务，还是逐个任务组，还是任意。但这后面再说。
        this.$set(item, "ableLearn", true);

        // 记录所有任务状态
        let mapTaskState = item.tasks.map((titem) => {
          return titem.state;
        });

        // 如果有一个任务是 在学并且当前的在学不是重新学习 则当前任务组即在学状态
        if (mapTaskState.indexOf(taskState['studying']) !== -1) {
          item.state = taskState['studying'];
        } else if (
          mapTaskState.indexOf(taskState['unstudy']) !== -1 &&
          mapTaskState.indexOf(taskState['studied']) !== -1
        ) {
          // 如果所有的任务都是已学状态 当前的任务组即已学状态
          item.state = taskState['studying'];
        } else if (mapTaskState.indexOf(taskState['unstudy']) !== -1) {
          item.state = taskState['unstudy'];
        } else {
          item.state = taskState['studied'];
        }

        item.tasks.forEach((titem, tindex) => {
          // titem.state = taskState['studying'];
          if (item.ableLearn) {
            // 如果当前任务组不是第一个任务组 并且当前任务组可以学习并且第一个任务是未学状态 将当前任务组的状态设为未学
            // 当前任务组的第一个任务开始学习后 当前任务组状态才为 在学状态
            // learnTaskIndex = tindex;
            this.$set(titem, "ableLearn", true);
          } else if (!item.ableLearn) {
            this.$set(titem, "ableLearn", false);
          }
        });
      });
    },
    // 在本地数据中获取一个任务的学习数据
    getLocalStorageTaskData(data) {
      let myStudyData = localStorage.getItem("studyData")
        ? JSON.parse(localStorage.getItem("studyData"))
        : {};
      let getCurrStudyData =
        myStudyData[this.courseInfo.currNo][this.userInfo.userID];
      let currTaskData = getCurrStudyData.find(
        (item) => item.taskID == data.taskID
      );
      return currTaskData;
    },
    // 获取任务学习进度
    handleChangeCourseLearnPro() {
      let Learned = 0;
      let Learning = 0;
      let uLearn = 0;
      let taskCount = 0;

      if (Array.isArray(this.content)) {
        this.content.forEach((item) => {
          item.tasks.forEach((titem) => {
            if (titem.state === taskState['studied']) Learned++;
            if (titem.state === taskState['studying']) Learning++;
            if (titem.state === taskState['unstudy']) uLearn++;
            taskCount++;
          });
        });
        let LearningSituation = `已学：${Learned}  在学：${Learning}  待学：${uLearn}`;
        this.$emit("handleChangeLSion", LearningSituation);
        this.$emit(
          "handleChangeProgress",
          parseInt((Learned / taskCount) * 100) || 0
        );
      }
    },
    // 引导文发生改变
    handleChangeSubmitContent(taskID) {
      // if (this.unSaveTaskID.indexOf(taskID) == -1) {
      //   this.unSaveTaskID.push(taskID);
      //   this.createBeforeunloadHandler();
      // }
    },
    // 任务保存后移除未保存的记录
    handleRemoveUnSaveTaskIDMark(taskID) {
      if (this.unSaveTaskID.indexOf(taskID) !== -1) {
        this.unSaveTaskID = this.unSaveTaskID.filter((item) => item !== taskID);
      }
    },
    // 时间改变
    handleChangeTime(data) {
      let findTaskGroup = this.content.find(
        (item) => item.taskGroupID === data.taskGroupID
      );
      let currDate = new Date();
      if (data.type == "taskGroup") {
        if (data.timeType == "start") {
          if (
            this.toMs(data.value) > this.toMs(findTaskGroup.cutOffTime) &&
            findTaskGroup.cutOffTime
          ) {
            findTaskGroup.beginTime = "";
          } else {
            findTaskGroup.beginTime = data.value;
          }
        } else {
          if (
            this.toMs(data.value) < this.toMs(findTaskGroup.beginTime) &&
            findTaskGroup.beginTime
          ) {
            findTaskGroup.cutOffTime = "";
          } else {
            findTaskGroup.cutOffTime = data.value;
          }
        }
        findTaskGroup.setTime = currDate;
        findTaskGroup.tasks.forEach((item) => {
          if (data.timeType == "start") {
            if (
              this.toMs(data.value) > this.toMs(item.cutOffTime) &&
              item.cutOffTime
            ) {
              item.beginTime = "";
            } else {
              item.beginTime = data.value;
            }
          } else {
            if (
              this.toMs(data.value) < this.toMs(item.beginTime) &&
              item.beginTime
            ) {
              item.cutOffTime = "";
            } else {
              item.cutOffTime = data.value;
            }
          }
          item.setTime = currDate;
        });
      } else {
        let findTask = findTaskGroup.tasks.find(
          (item) => item.taskID === data.taskID
        );
        if (data.timeType == "start") {
          if (
            this.toMs(data.value) > this.toMs(findTask.cutOffTime) &&
            findTask.cutOffTime
          ) {
            findTask.beginTime = "";
          } else {
            findTask.beginTime = data.value;
          }
        } else {
          if (
            this.toMs(data.value) < this.toMs(findTask.beginTime) &&
            findTask.beginTime
          ) {
            findTask.cutOffTime = "";
          } else {
            findTask.cutOffTime = data.value;
          }
        }
        findTask.setTime = currDate;
      }
      this.$forceUpdate();
    },
    toMs(data) {
      return !data ? 0 : new Date(data).getTime();
    },
    // 确认限时
    async handleConfirmTime(data) {
      let findTaskGroup = this.content.find(
        (item) => item.taskGroupID === data.taskGroupID
      );
      if (data.type === "taskGroup") {
        let nData = this.nTaskSettings || {};
        findTaskGroup.tasks.forEach((item) => {
          nData[item.taskID] = {
            currNo: this.courseInfo.currNo,
            taskID: item.taskID,
            beginTime: item.beginTime,
            cutOffTime: item.cutOffTime,
            setTime: item.setTime,
            state: "生效",
            canVote: this.nTaskSettings?.[item.taskID]?.canVote,
            voteID: this.nTaskSettings?.[item.taskID]?.voteID
          };
        });
        let isSet = await this.handleChangeCurrCouserInfo(nData);
        if (isSet) {
          // this.$set(this.nTaskSettings,)
          findTaskGroup.tasks.forEach((item) => {
            if (!this.nTaskSettings) this.nTaskSettings = {}
            this.nTaskSettings[item.taskID] = nData[item.taskID];
          });
        }
      } else {
        let findTask = findTaskGroup.tasks.find(
          (item) => item.taskID === data.taskID
        );
        if (findTask.beginTime || findTask.cutOffTime) {
          let nData = Object.assign({}, this.nTaskSettings || {}) || {};
          const newAddObj = {
            currNo: this.courseInfo.currNo,
            taskID: findTask.taskID,
            beginTime: findTask.beginTime,
            cutOffTime: findTask.cutOffTime,
            setTime: findTask.setTime,
            state:
              this.nTaskSettings &&
                this.nTaskSettings[data.taskID]?.state == "生效"
                ? "关闭"
                : "生效",
            canVote: this.nTaskSettings?.[data.taskID]?.canVote,
            voteID: this.nTaskSettings?.[data.taskID]?.voteID
          };
          nData[data.taskID] = newAddObj;
          let isSet = await this.handleChangeCurrCouserInfo(nData);
          if (isSet) {
            if (!this.nTaskSettings) this.$set(this, 'nTaskSettings', {})
            this.$set(this.nTaskSettings, data.taskID, newAddObj);
          }
        } else {
          this.$antdMessage.warning({
            content: "请先给任务设置至少一个时间！",
          });
        }
      }
      this.$forceUpdate();
    },
    // 修改投票配置
    async handleConfirmVote(data, name) {
      if (!this.pageRouteIsTeacher) return
      const taskID = data.taskID || this.taskID_Vote
      let findTaskSetting = this.nTaskSettings?.[taskID]
      let nData = Object.assign({}, this.nTaskSettings) || {};
      const newAddObj = {
        currNo: this.courseInfo.currNo,
        taskID: taskID
      };
      if (findTaskSetting) {
        Object.assign(newAddObj, findTaskSetting)
        if (name == 'canVote') {
          newAddObj.canVote = data.canVote
        } else {
          newAddObj.voteID = data.voteData?.voteID
        }
      } else {
        this.$set(this.nTaskSettings, taskID, newAddObj);
        if (name == 'canVote') {
          newAddObj.canVote = data.canVote
        } else {
          newAddObj.voteID = data.voteData?.voteID
        }
      }
      nData[taskID] = newAddObj
      let isSet = await this.handleChangeCurrCouserInfo(nData);
      if (isSet) this.$set(this.nTaskSettings, taskID, newAddObj);
      this.handleIframeClose()
    },
    // 打开投票编辑弹窗
    openVoteDialog(data, type) {
      if (type == 'create') {
        this.iframeRouter = `${location_QuestionBank(window)}/taskvote/add`
      } else {
        this.iframeRouter = `${location_QuestionBank(window)}/taskvote/${data.voteID}`
      }
      this.iframeRouter += `?currNo=${this.courseInfo.currNo}&taskID=${data.taskID}`
      this.taskID_Vote = data.taskID
      this.showVoteDialog = true
    },
    // 打开编辑投票项弹窗
    handleOpenEditVoteItem(data) {
      this.iframeRouter = `${location_QuestionBank(window)}/voteitem`
      this.iframeRouter += `?voteID=${data.voteID}&op=${data.voteItemID}`
      this.showVoteDialog = true
    },
    // 关闭投票弹窗
    handleIframeClose() {
      this.iframeRouter = ""
      this.showVoteDialog = false
      this.taskID_Vote = null
    },
    // 保存投票项ID
    async SaveVoteItemID(data, voteItemID, message) {
      const result = await this.handelSubmitData({
        currNo: Number(this.courseInfo.currNo),
        taskIndex: data.taskGroupID + '-' + data.taskID,
        taskGroupID: data.taskGroupID,
        taskID: data.taskID,
        name: data.name,
      }, true, null, false, data, message)
      let taskGroup = this.content.find(item => item.taskGroupID == data.taskGroupID)
      let task = taskGroup.tasks.find(item => item.taskID == data.taskID)
      if (!task.guidelines[0].studyData) {
        this.loadingTasks.push(data.taskIndex);
        let myStudyData = localStorage.getItem("studyData")
          ? JSON.parse(localStorage.getItem("studyData"))
          : {};
        let getCurrStudyData = myStudyData[this.courseInfo.currNo][this.userInfo.userID];
        const currTaskData = getCurrStudyData.find(
          (item) => item.taskID == data.taskID
        );

        this.$set(task?.guidelines?.[0], 'studyData', currTaskData.guidelineResults[1])
      }
      // task.guidelines[0]?.studyData?.voteItemID
      this.$set(task?.guidelines?.[0]?.studyData, 'voteItemID', voteItemID)
      this.$forceUpdate()
      // if (result) {
      //   this.$antdMessage.success({content: "保存成功！"})
      // }
    },
    // 修改投票项信息
    updateVoteItemInfo(titem, oldLink, task, voteID) {
      const findFirstGuideline = Object.keys(titem.guidelineResults).map((item, index) => { if (index == 0) return titem.guidelineResults[item] })
      if (!findFirstGuideline[0].voteItemID || !voteID) return
      const params = {
        itemDetailLink: findFirstGuideline[0].submitContent?.data?.showLink,
        voteItemID: findFirstGuideline[0].voteItemID,
        voteID
      };
      // if (oldLink == params.itemDetailLink) return
      updateVoteItem(params).then(res => {
        if (res.errno == 0) {
          this.$set(task.guidelines[0].studyData.submitContent, "data", params.itemDetailLink)
          this.$antdMessage.success({ content: "修改投票项链接成功!" })
        } else {
          this.$antdMessage.error({ content: res.message || "修改投票项链接失败,请重新保存!" })
        }
      })
      sessionStorage.removeItem(`/api/voteitem/list?voteID=${voteID}&needAll=true`)
      sessionStorage.removeItem(`/api/voteitem/list?voteID=${voteID}`)
    },
    // 修复投票项，删除投票项ID
    handleFixedVoteItem(item, voteItemID = 0) {
      const voteID = this.getVoteID(item.taskID)
      const _voteItemID = this.getVoteItemID(item)
      const params = {
        voteID,
        id: _voteItemID
      }
      getVoteItem(params).then(res => {
        if (res.errno == 0) {
          if (res?.data?.voteItemID && res.data.state !== '已删除') {
            this.$antdMessage.success({ content: "无需修复!" })
          }
        } else {
          // 判断studyData是否存在 且是否有内容
          const currNo = this.courseInfo.currNo
          let localData = localStorage.getItem("studyData");
          localData = localData ? JSON.parse(localData) : {};
          if (!localData[currNo]) localData[currNo] = {}
          let mystudydata = localData[currNo]?.[this.userInfo.userID];
          if (!mystudydata) {
            mystudydata = [];
          }
          const oldTaskResult = mystudydata.find(
            (e) => e.taskID == item.taskID
          );
          let guidelineID = null;
          Object.keys(oldTaskResult.guidelineResults).forEach((key, index) => {
            if (index == 0) guidelineID = key
          });
          oldTaskResult.guidelineResults[guidelineID].voteItemID = null;
          localData[currNo][this.userInfo.userID] = mystudydata;
          localStorage.setItem("studyData", JSON.stringify(localData));
          this.SaveVoteItemID(item, null, "修复成功!")
        }
      })
    },
    // 修改已开设课程信息
    handleChangeCurrCouserInfo(data) {
      return new Promise((resolve) => {
        let params = {
          courseID: this.courseInfo.courseID,
          currNo: this.courseInfo.currNo,
          taskSettings: data,
        };
        updatecurr(params).then((res) => {
          if (res.errno === 0) {
            localStorage.removeItem("courseInfo")
            this.$antdMessage.success({
              content: "设置成功!",
            });
            resolve(true);
          } else {
            this.$antdMessage.error({
              content: "设置失败!",
            });
            resolve(false);
          }
        });
      });
    },
    handleChangeIsHide(taskitem) {
      console.log(taskitem);
      const taskSetting = this.nTaskSettings
      let taskObj = {}
      // 如果任务设置中有当前任务,将它赋值在taskObj中
      if (taskSetting[taskitem.taskID]) {
        taskObj = taskSetting[taskitem.taskID]
        taskObj.taskID = taskitem.taskID
      } else {
        taskObj.taskID = taskitem.taskID
      }
      taskObj.isHide = taskitem.isHide
      taskSetting[taskitem.taskID] = taskObj
      this.handleChangeCurrCouserInfo(taskSetting)
    },
    // 上传文件后保存学习数据 
    handleUploadFileSaveData(data) {
      data.currNo = this.courseInfo.currNo
      this.handelSubmitData(data)
    },
    //添加beforeunload监听事件 离开、关闭页面
    createBeforeunloadHandler() {
      if (this.isLinstened) return;
      this.isLinstened = true;
      // window.onbeforeunload = function () {
      //   return "还有信息未保存";
      // };
      window.addEventListener("beforeunload", this.beforeunloadHandler, false);
    },
    //移除beforeunload事件
    destroyedBeforeunloadHandler() {
      window.removeEventListener(
        "beforeunload",
        this.beforeunloadHandler,
        false
      );
      this.isLinstened = false;
    },
    /**
     * @description beforeunload监听事件 MDN Web Docs https://developer.mozilla.org/zh-CN/docs/Web/API/Window/beforeunload_event
     */
    beforeunloadHandler: (event) => {
      // Cancel the event as stated by the standard.
      event.preventDefault();
      // Chrome requires returnValue to be set.
      event.returnValue = "";
    },
    /**
     * @description 添加切换路由监听 检测数据是否尚未保存
     */
    async leaveRouteBefore(next, action) {
      if (action === "confirm") {
        this.destroyedBeforeunloadHandler();
        const courseID = Number(this.courseInfo.courseID);
        if (courseID) {
          // let isSave = await this.updateCourseInfo(courseID);
          next();
        } else {
          // let isSave = await this.pushCourseInfo();
          next();
        }
      } else {
        this.destroyedBeforeunloadHandler();
        next();
      }
    },
    /**
     * @description 检查数据是否已保存
     */
    beforLeaveCheckIsSave(next) {
      if (this.isLinstened && this.unSaveTaskID.length) {
        this.$confirm(
          "新的学习数据还未保存，确定将自动保存数据、取消则不保存数据，并离开当前页面！",
          {
            title: "提示",
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
            callback: (action) => {
              this.leaveRouteBefore(next, action);
            },
          }
        );
      } else {
        next();
      }
    },
    // 保存题库系统中创建的session_id
    async handleUpdateSessionID(
      { taskGroupID, taskID, name, guidelineID },
      dom,
      params,
      session_id
    ) {
      params.taskDetail = this.getLocalStorageTaskData({ taskID });
      params.isSave = "saved";
      let saveSessionID = await this.handelSubmitData({
        currNo: Number(this.courseInfo.currNo),
        taskIndex: taskGroupID + "-" + taskID,
        taskGroupID: taskGroupID,
        taskID: taskID,
        name: name,
      });
      if (saveSessionID) {
        let findGuideline = this.content
          .find((item) => item.taskGroupID === taskGroupID)
          .tasks.find((item) => item.taskID === taskID)
          .guidelines.find((item) => item.guidelineID === guidelineID);
        if (!findGuideline.studyData)
          findGuideline.studyData =
            params.taskDetail.guidelineResults[params.currGuidelineID];
        this.$set(findGuideline.studyData, "session_id", session_id);

        dom.contentWindow.postMessage(
          JSON.stringify(params),
          location_QuestionBank(window)
        );
        // dom.contentWindow.postMessage(
        //   JSON.stringify(params),
        //   "http://localhost:3000"
        // );
      } else {
        this.$antdMessage.error({
          content: "保存题组信息失败，请刷新页面重试!",
        });
      }
    },
    async handleUpdateTaskScore(
      { taskGroupID, taskID, name, guidelineID },
      dom,
      params,
      session_id,
      taskIsOnlyGuideline, groupItem, taskItem
    ) {
      if (session_id) {
        let findGuideline = this.content
          .find((item) => item.taskGroupID === taskGroupID)
          .tasks.find((item) => item.taskID === taskID)
          .guidelines.find((item) => item.guidelineID === guidelineID);
        if (!findGuideline.studyData)
          findGuideline.studyData =
            params.taskDetail.guidelineResults[params.currGuidelineID];
        this.$set(findGuideline.studyData, "session_id", session_id);
      }
      // isAuto保存学习数据时会将任务的状态设为已学
      const isAuto = taskIsOnlyGuideline
      const res = await this.handelSubmitData({
        currNo: Number(this.courseInfo.currNo),
        taskIndex: taskGroupID + "-" + taskID,
        taskGroupID: taskGroupID,
        taskID: taskID,
        name: name,
      }, isAuto);
      if (res && isAuto) {
        this.changeToTaskStated(groupItem, taskItem, {
          state: "已学",
        });
      }
      dom.contentWindow.postMessage(
        JSON.stringify(params),
        location_QuestionBank(window)
      );
      // dom.contentWindow.postMessage(
      //   JSON.stringify(params),
      //   "http://localhost:3000"
      // );
    },
    sendMessage(msg) {
      if (this.client) {
        sendMessageByClient(
          {
            message: (this.userInfo.realName || this.userInfo.email || this.userInfo.nickName || this.userInfo.stuNum || "其它用户") + ":" + msg,
            roomName: this.roomName + this.$route.params.id,
            type: "task",
          },
          this.client
        );
      }
    },
  },
  async mounted() {
    this.courseInfo.content && (this.content = this.courseInfo.content);
  },
  beforeDestroy() {
    // 页面销毁前 移除监听事件
    this.destroyedBeforeunloadHandler();
    if (this.client) {
      this.client.closing();
    }
  },
  beforeRouteLeave(to, from, next) {
    this.beforLeaveCheckIsSave(next);
  }
};
</script>

<style lang="stylus">
.courseTask {
  padding-top: 40px;
  padding-bottom: 40px;

  .rankingList {
    display: none;
  }

  .mustInput {
    cursor: pointer;
    position: absolute;
    left: -20px;
    font-family: Segoe UI;
    font-size: 16px;
    color: #f8060e;
    transform: translate(0, -50%);

    img {
      cursor: pointer;
      object-fit: cover;
      width: 12px !important;
      height: 12px !important;
    }
  }

  .chioceInput {
    cursor: pointer;
    position: absolute;
    left: -20px;
    font-family: Segoe UI;
    font-size: 16px;
    color: #fed48c;
    transform: translate(0, -50%);
  }

  .introduction {
    padding: 21px 26px;
    // margin-top: 40px;
    position: relative;
    max-width: 835px;
    min-height: 130px;
    background-color: #ffffff;
    box-shadow: 0px 8px 16px 0px rgba(7, 23, 39, 0.1);
    border-radius: 18px;
    font-family: PMingLiU-ExtB;
    font-size: 14px;
    color: #000000;
  }

  .taskForce {
    max-width: 835px;

    .el-collapse {
      border: 0;

      .el-collapse-item {
        position: relative;
        padding: 21px 0 15px;
        margin-top: 31px;
        background-color: #ffffff;
        box-shadow: 0px 8px 16px 0px rgba(7, 23, 39, 0.1);
        border-radius: 18px;
        transition: all 0.2s linear;

        .el-collapse-item__header, .el-collapse-item__wrap {
          border: 0;
        }

        .el-collapse-item__header {
          padding: 4px 31px 6px 26px;
          align-items: center;
          justify-content: space-between;
          height: auto;
          line-height: 1;
          font-size: 16px;
          font-weight: bold;
          color: #000000;
          transition: all 0.1s linear;

          img {
            vertical-align: bottom;
            margin-right: 8px;
            object-fit: cover;
            user-select: none;
            height: 22px;
          }

          .el-collapse-item__arrow {
            margin: 0;
          }

          .el-collapse-item__arrow .el-icon-arrow-right {
            display: none;
          }

          .el-icon-arrow-right:before {
            content: none;
          }

          .taskController {
            display: flex;
            align-items: center;
            margin: 0 45px 0 auto;

            button {
              cursor: pointer;
              outline: none;
              width: 72px;
              height: 29px;
              border-radius: 5px;
              border: none;
              font-family: Yu Gothic UI;
              font-size: 14px;
              color: #ffffff;
            }

            .saveData {
              margin-right: 20px;
              background: #f6ad35;
            }

            .VoteIsNotCreated {
              cursor: not-allowed;
              background: #bfbfbf;
            }

            .startLearning {
              background: #f6ad35;
            }

            .endLearn {
              background: #02497c;
            }

            .reLearning {
              background: #5ad551;
            }
          }

          .icondown2Box {
            margin: 0 0 0 auto;
            transition: transform 0.2s linear;

            .icondown2 {
              font-size: 22px;
              color: #8a8a8a;
            }

            .downIcon {
              margin: 0;
              object-fit: cover;
              height: 100%;
            }
          }

          .tNfinishIcon {
            // width: 19px;
            height: 22px;
          }

          .groupAndtaskIconPath {
            margin-right: 8px;
            width: 30px;
            height: 22px;

            img {
              z-index: 99;
              margin: 0;
              -o-object-fit: cover;
              object-fit: cover;
              width: 30px;
              height: 30px;
              border-radius: 50%;
              transform: translate(-5%, -10%);
            }
          }

          .taskName {
            padding-top: 5px;
            max-width: 90%;
            font-family: PMingLiU-ExtB;
            font-size: 16px;
            color: #000000;
            text-overflow: ellipsis;
            word-break: break-all;
          }
        }

        .el-collapse-item__wrap {
          // background: #f9f9f9;
          .el-collapse-item__content {
            position: relative;
            padding-bottom: 52px;

            .retract {
              cursor: pointer;
              position: absolute;
              bottom: 0;
              width: 50px;
              height: 4px;
              left: calc(((100% - 50px) / 2));
              background: #bfbfbf;
            }

            .task-content {
              .el-collapse-item {
                // margin-top: 20px;
                .el-collapse-item__header {
                  min-height: 32px;
                  position: relative;
                  padding-top: 0;
                  // padding-bottom: 17px;
                  padding-bottom: 0;

                  .taskName {
                    font-family: PMingLiU-ExtB;
                    font-size: 16px;
                    color: #000000;
                  }
                }

                .el-collapse-item__wrap {
                  .el-collapse-item__content {
                    padding: 4px 27px 40px;
                    background: #fff;

                    .taskDesc {
                      position: relative;
                      font-family: fangsong;
                      font-size: 16px;
                      font-weight: bold;

                      .desc {
                        p:first-child {
                          display: inline-block;
                        }
                      }

                      .mustInput, .chioceInput {
                        top: 50%;
                      }
                    }
                  }
                }
              }

              .isChoose {
                .el-collapse-item__header::after {
                  position: absolute;
                  content: '';
                  left: 0;
                  top: 0;
                  width: 3px;
                  height: 25px;
                  background: #8a8a8a;
                  transform: translate(0, 15%);
                }
              }

              .el-collapse-item:first-child {
                margin-top: 0;
              }

              .icondown2Box {
                transform: rotate(0);
              }

              .is-active {
                background: #fff;

                .el-collapse-item__wrap {
                  overflow: unset !important;
                }

                .el-collapse-item__header {
                  margin-bottom: 15px;

                  // padding-bottom: 17px;
                  .icondown2Box {
                    transform: rotate(180deg);
                  }
                }

                .el-collapse-item__content::after {
                  content: none;
                }
              }

              .isFinishAndLearing {
                .el-collapse-item__header::after {
                  background: #f6ad35;
                }
              }

              .el-collapse {
                .el-collapse-item {
                  .el-collapse-item__header {
                    .icondown2Box {
                      margin: 0;
                    }

                    .btnUnShow {
                      margin: 0 0 0 auto;
                    }
                  }
                }
              }
              .isHide {
                display: none;
              }
            }
          }
        }
      }

      .is-active {
        position: relative;
        background-color: #f9f9f9;

        .el-collapse-item__wrap {
          background: #f9f9f9;
          overflow: unset;
        }

        .el-collapse-item__header {
          padding-bottom: 24px;
        }

        .icondown2Box {
          transform: rotate(180deg);
        }
      }
    }
  }

  .finishDialog {
    .el-dialog__header {
      padding: 0;

      .el-dialog__headerbtn {
        display: none;
      }
    }

    .el-dialog__body {
      padding: 25px 55px 0;

      .title {
        text-align: center;
        font-family: PMingLiU-ExtB;
        font-size: 14px;
        font-weight: bold;
        color: #000;
      }

      .tips {
        margin-top: 10px;
        text-align: center;
        font-family: PMingLiU-ExtB;
        font-size: 14px;
        color: #f6ad35;
      }
    }

    .el-dialog__footer {
      padding-bottom: 30px;

      .el-button--default {
        padding: 0;
        width: 55px;
        height: 25px;
        background: #fff;
        border-radius: 5px;
        border: solid 1px #d6d6d6;
        font-family: PMingLiU-ExtB;
        font-size: 14px;
        color: #666;
      }

      .el-button--primary {
        margin-left: 50px;
        padding: 0;
        width: 55px;
        height: 25px;
        background: #02497c;
        border-radius: 5px;
        border: none;
        font-family: PMingLiU-ExtB;
        font-size: 14px;
        color: #fff;
      }
    }
  }
}

@media only screen and (min-width: 768px) and (max-width: 1024px) {
  .courseTask {
    padding: 0 9vw 6vw 10vw;

    .rankingList {
      position: relative;
      padding: 3vw 0 4vw 0;
      // display: flex;
      align-items: center;
      justify-content: space-between;
      flex-flow: column;
      height: 39vw;
      background-color: #ffffff;
      box-shadow: 0vw 1vw 2vw 0vw rgba(0, 0, 0, 0.16);
      border-radius: 3vw;

      .title {
        font-family: Segoe UI;
        font-size: 4vw;
        color: #035386;
      }

      .userRank {
        padding: 0 2vw 0 7vw;
        display: flex;
        justify-content: space-between;

        .topList {
          margin-right: 3vw;
          display: flex;
          justify-content: space-between;
          align-items: flex-end;
          width: 28vw;
          height: 13vw;

          .user {
            .picture {
              margin-bottom: 1vw;
              position: relative;
              width: 6vw;
              height: 6vw;
              background-color: rgba(195, 195, 195, 0.68);
              border-radius: 50%;

              .iconBox {
                position: absolute;
                top: -20px;
                left: 0;
                transform: translate(9%, 0%);
              }

              .firstIcon {
                top: -25px;
                transform: translate(-1%, 0%);
              }
            }

            .name {
              width: 6vw;
              height: 3vw;
              background-color: #f6ad35;
              border-radius: 11px;
              text-align: center;
              font-family: Yu Gothic UI;
              font-size: 2vw;
              color: #ffffff;
              overflow: hidden;
            }
          }
        }

        .dynamic {
          padding: 0 7px 0 5px;
          display: flex;
          flex-flow: column;
          justify-content: space-around;
          width: 42vw;
          height: 14vw;
          background-color: #ffffff;
          border: solid 1px #f5f5f5;

          .user {
            display: flex;
            align-items: center;
            justify-content: space-around;

            .name {
              margin-right: 5px;
              width: 7vw;
              height: 3vw;
              background-color: #000000;
              border-radius: 11px;
              text-align: center;
              line-height: 3vw;
              font-family: Yu Gothic UI;
              font-size: 12px;
              color: #ffffff;
            }

            .desc {
              flex: 1;
              display: flex;
              align-items: center;
              justify-content: space-between;

              .task {
                font-family: Microsoft JhengHei UI;
                font-size: 14px;
                color: #035386;
              }

              .time {
                font-family: YouYuan;
                font-size: 12px;
                color: #035386;
              }
            }
          }
        }
      }

      .btn {
        button {
          width: 32vw;
          height: 5vw;
          background-color: #035386;
          border-radius: 3vw;
          font-size: 5vw;
          line-height: 5vw;
          color: #ffffff;
          border: none;
          outline: none;
        }
      }
    }

    .rankingList::after {
      position: absolute;
      content: '';
      width: 39px;
      height: 3px;
      background-color: #bfbfbf;
      border-radius: 2px;
      bottom: 1vw;
    }

    .introduction {
      margin-top: 3vw;
    }
  }
}

@media only screen and (max-width: 767px) {
  .courseTask {
    .taskForce {
      .el-collapse {
        .el-collapse-item {
          .el-collapse-item__wrap {
            .el-collapse-item__content {
              .task-content {
                .el-collapse {
                  .el-collapse-item {
                    .el-collapse-item__header {
                      .timeRemaining {
                        display: none;
                      }

                      .taskController {
                        margin: 0 25px 0 auto;
                      }
                    }
                  }

                  .el-collapse-item__wrap {
                    .el-collapse-item__content {
                      padding: 4px 4px 20px;

                      .taskDesc {
                        position: relative;
                        padding: 0 16px;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
</style>